package com.example.springbooteasycode.utils.qrcode.withText;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class QRCodeGeneratorWithText {

    public static void main(String[] args) {
        String qrData = "https://www.baidu.com";
        int qrWidth = 200; // 小二维码的宽度
        int qrHeight = 200; // 小二维码的高度
        int backgroundWidth = 300; // 背景的宽度
        int backgroundHeight = 300; // 背景的高度
        String outputFileName = "qrcode_with_background_and_info.png";

        try {
            // 创建背景图像
            BufferedImage backgroundImage = createBackground(backgroundWidth, backgroundHeight);

            // 在背景上生成二维码
            BufferedImage qrCodeImage = generateQRCode(qrData, qrWidth, qrHeight);

            // 计算二维码在背景上的位置
            int xPosition = (backgroundWidth - qrWidth) / 2;
//            int yPosition = (backgroundHeight - qrHeight) / 2;
            int yPosition = 10;


            // 将二维码放在背景的中心
            Graphics2D g2d = backgroundImage.createGraphics();
            g2d.drawImage(qrCodeImage, xPosition, yPosition, null);

            // 添加文本信息
            addTextToBackground(g2d, "编号: 8924062617520001259104", Color.BLACK, 15, 230);
            addTextToBackground(g2d, "名称: A5", Color.BLACK, 15, 250);
            addTextToBackground(g2d, "位置: 1号楼-1单元-2层-201室哈哈哈哈哈哈哈哈都是多少", Color.BLACK, 15, 270);

            g2d.dispose();

            // 保存最终的图像
            saveImage(backgroundImage, outputFileName);

            System.out.println("QR code with background and info generated and saved as: " + outputFileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static BufferedImage createBackground(int width, int height) {
        BufferedImage backgroundImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = backgroundImage.createGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(Color.WHITE);
        g2d.fill(new RoundRectangle2D.Float(0, 0, width, height, 10f, 10f));
        g2d.dispose();
        return backgroundImage;
    }

    private static BufferedImage generateQRCode(String data, int width, int height) throws WriterException, IOException {
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
        BitMatrix bitMatrix = qrCodeWriter.encode(data, BarcodeFormat.QR_CODE, width, height, hints);
        MatrixToImageConfig config = new MatrixToImageConfig(MatrixToImageConfig.BLACK, MatrixToImageConfig.WHITE);
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        MatrixToImageWriter.writeToStream(bitMatrix, "PNG", stream, config);
        byte[] bytes = stream.toByteArray();
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        return ImageIO.read(bais);
    }

    private static void addTextToBackground(Graphics2D g2d, String text, Color color, int fontSize, int yPosition) {
        g2d.setColor(color);
        g2d.setFont(new Font("Arial", Font.BOLD, fontSize));
        g2d.drawString(text, 50, yPosition);
    }

    private static void saveImage(BufferedImage image, String fileName) throws IOException {
        Path path = Paths.get(fileName);
        ImageIO.write(image, "png", path.toFile());
    }

}
